const TAG = "DragAcr"

export default class DragAcr {
    constructor(param) {
        this.initParam(param)
        this.draw(this.value)
    }

    initParam(param) {
        const {
            el,
            startAngle = 0,
            endAngle = 2,
            width = 252,
            innerColor = "green",
            outColor = "#08000000",
            innerLineWidth = 1,
            outLineWidth = 24,
            counterclockwise = false,
            slider = 8,
            color = ["#ffffff", "#0F75F3", "#54C8A5", "#FEDB00", "red"],
            sliderColor = "#ffffff",
            sliderBorderColor = "#33aaff",
            value = 0,
            change = (v) => {
                console.log(v)
            },
            textShow = true,
        } = param;

        this.el = el;
        this.width = width;
        this.height = width;
        this.center = this.width / 2
        this.outLineWidth = outLineWidth;
        this.radius = this.width / 2 - this.outLineWidth / 2;
        // this.ctx = el.getContext("2d");
        this.ctx = this.el.getContext('2d', {
            antialias: true
        });

        this.startAngle = startAngle;
        this.endAngle = endAngle;
        this.innerColor = innerColor;
        this.outColor = outColor;
        this.innerLineWidth = innerLineWidth;
        this.counterclockwise = counterclockwise;
        this.slider = slider;
        this.color = color;
        this.sliderColor = sliderColor;
        this.sliderBorderColor = sliderBorderColor;
        this.value = value;
        this.textShow = textShow;
        this.change = change;
        this.isDown = false;

        console.log(TAG + ';initParam el:' + el);
        console.log(TAG + ';initParam  width:' + this.width);
        console.log(TAG + ';initParam  height:' + this.height);
        console.log(TAG + ';initParam  center:' + this.center);
        console.log(TAG + ';initParam  radius:' + this.radius);
        console.log(TAG + ';initParam  ctx:' + this.ctx);
        console.log(TAG + ';initParam  outLineWidth:' + this.outLineWidth);
    }

    // 绘图
    draw(value) {
        console.log(TAG + ';draw  value:' + value);
        if (value == undefined) {
            value = this.value;
        } else {
            this.value = value;
        }

        this.ctx.clearRect(0, 0, this.width, this.width);
        this.ctx.save();

        let startDeg = this.counterclockwise ? Math.PI * (2 - this.startAngle) : Math.PI * this.startAngle
        let endDeg = this.counterclockwise ? Math.PI * (2 - this.endAngle) : Math.PI * this.endAngle


        // 绘制背景圆
        this.ctx.beginPath();
        this.ctx.arc(this.center, this.center, this.radius, startDeg,
            endDeg, this.counterclockwise);
        this.ctx.strokeStyle = this.outColor;
        this.ctx.lineCap = "round";
        this.ctx.lineWidth = this.outLineWidth;
        this.ctx.stroke();

        let Deg = this.valToDeg(value)
        this.drawOne(startDeg, value);

        if (value > 25) {
            // 绘制可变圆弧
            this.drawTwo(value);
        }

        if (value > 50) {
            // 绘制可变圆弧
            this.drawThree(value);
        }

        if (value > 75) {
            this.drawFour(value)
        }

        // 绘制滑块bar
        this.P = this.DegToXY(Deg)
        this.ctx.beginPath();
        this.ctx.moveTo(this.center, this.center,);
        this.ctx.arc(this.P.x, this.P.y, this.outLineWidth / 2, 0, Math.PI * 2, false); // 绘制滑块内侧
        this.ctx.fillStyle = this.sliderBorderColor;
        this.ctx.fill();
        this.ctx.beginPath();
        this.ctx.moveTo(this.center, this.center);
        this.ctx.arc(this.P.x, this.P.y, this.slider, 0, Math.PI * 2, false); // 绘制滑块
        this.ctx.fillStyle = this.sliderColor;
        this.ctx.fill();

        // 文字
        if (this.textShow) {
            this.ctx.font = '60px HarmonyHeiTi, HarmonyHeiTi-Medium';
            this.ctx.fillStyle = "#000000";
            this.ctx.textAlign = "center"
            this.ctx.textBaseline = "middle";
            this.ctx.fillText(this.value + "", this.center, this.center);
        }

        //  this.drawLine();
    }

    drawLine() {
        const grad = this.ctx.createLinearGradient(0, this.width / 2, 0, this.width);
        // Add three color stops
        grad.addColorStop(0.0, this.color[0]);
        grad.addColorStop(1.0, this.color[1]);

        this.ctx.beginPath();
        this.ctx.lineWidth = '34';
        this.ctx.strokeStyle = grad;
        this.ctx.moveTo(0, 0);
        this.ctx.lineTo(this.width, this.width);
        this.ctx.stroke();
    }

    // 0 - =25
    drawOne(startDeg, value) {
        if (value > 25) {
            value = 25;
        }

        // 绘制可变圆弧
        const grad = this.ctx.createLinearGradient(0, this.width / 2, 0, this.width);
        // Add three color stops
        grad.addColorStop(0.0, this.color[0]);
        grad.addColorStop(1.0, this.color[1]);
        let startDeg2 = this.getStartDeg(0);
        let deg = this.valToDeg(value)
        // 绘制可变圆弧
        this.drawARC(startDeg2, deg, grad);
    }

    // 25 - =50
    drawTwo(value) {
        if (value > 50) {
            value = 50;
        }
        // 绘制可变圆弧
        const grad = this.ctx.createLinearGradient(0, this.width, 0, this.width / 2);
        // Add three color stops
        grad.addColorStop(0.0, this.color[1]);
        grad.addColorStop(1.0, this.color[2]);
        let deg = this.valToDeg(value)
        let startDeg2 = this.getStartDeg(0.5);
        // 绘制可变圆弧
        this.drawARC(startDeg2, deg, grad);
    }

    // 50 - =75
    drawThree(value) {
        if (value > 75) {
            value = 75;
        }
        const grad = this.ctx.createLinearGradient(0, this.width / 2, 0, 0);
        // Add three color stops
        grad.addColorStop(0.0, this.color[2]);
        grad.addColorStop(1.0, this.color[3]);
        let startDeg2 = this.getStartDeg(1);
        let deg = this.valToDeg(value)
        // 绘制可变圆弧
        this.drawARC(startDeg2, deg, grad);
    }

    drawFour(value) {
        if (value > 100) {
            value = 100;
        }
        const grad = this.ctx.createLinearGradient(0, 0, 0, this.width / 2);
        // Add three color stops
        grad.addColorStop(0.0, this.color[3]);
        grad.addColorStop(1.0, this.color[4]);
        let startDeg2 = this.getStartDeg(1.5);
        let deg = this.valToDeg(value)
        // 绘制可变圆弧
        this.drawARC(startDeg2, deg, grad);
    }

    drawARC(startDeg, endDeg, grad) {
        // 绘制可变圆弧
        this.ctx.beginPath();
        this.ctx.arc(this.center, this.center, this.radius, startDeg, endDeg, this.counterclockwise); // 可变圆弧
        this.ctx.strokeStyle = grad;
        this.ctx.lineCap = "round";
        this.ctx.lineWidth = this.outLineWidth;
        this.ctx.stroke();
    }


    //将值转化为弧度
    valToDeg(v) {
        //  console.log(TAG + ' ;valToDeg v:' + v);
        let range = this.endAngle - this.startAngle;
        // console.log(TAG + ' ;valToDeg range:' + range);
        let val = range / 100 * v;
        //  console.log(TAG + ' ;valToDeg val:' + val);
        if (this.counterclockwise && (val != 0)) val = 2 - val;
        let startDeg = this.counterclockwise ? (2 - this.startAngle) : this.startAngle;
        return (startDeg + val) * Math.PI;
    }
    // 弧度转化为对应坐标值
    DegToXY(deg) {
        let d = 2 * Math.PI - deg;
        return this.respotchangeXY({
            x: this.radius * Math.cos(d),
            y: this.radius * Math.sin(d)
        })
    }

    //canvas坐标转化为中心坐标
    spotchangeXY(point) {
        const spotchangeX = (i) => {
            return i - this.center
        }
        const spotchangeY = (i) => {
            return this.center - i
        }
        return {
            x: spotchangeX(point.x),
            y: spotchangeY(point.y)
        }
    }

    //中心坐标转化为canvas坐标
    respotchangeXY(point) {
        const spotchangeX = (i) => {
            return i + this.center
        }
        const spotchangeY = (i) => {
            return this.center - i
        }
        return {
            x: spotchangeX(point.x),
            y: spotchangeY(point.y)
        }
    }

    getStartDeg(startAngle) {
        return this.counterclockwise ? Math.PI * (2 - startAngle) : Math.PI * startAngle
    }

    OnMouseMove(evt) {
        if (!this.isDown) return;
        let evpoint = {};
        evpoint.x = this.getx(evt);
        evpoint.y = this.gety(evt);
        let point = this.spotchangeXY(evpoint);
        let deg = this.XYToDeg(point.x, point.y);
        //   console.log(TAG + '; OnMouseMove deg XYToDeg ...' + deg);
        deg = this.counterclockwise ? deg : Math.PI * 2 - deg;
        //  console.log(TAG + '; OnMouseMove deg...' + deg);

        let val = (deg / Math.PI - this.startAngle) / (this.endAngle - this.startAngle) * 100
        val = Math.round(val)
        //  console.log(TAG + '; OnMouseMove val:' + val);
        if (val < 0) val = 100 + val;
        if (val <= 0) val = 0;
        if (val > 100) {
            if (this.value > 75) {
                val = 100;
            } else {
                val = val - 100;
            }
        }
        if (val > 75) {
            if (this.value < 25) {
                val = 0;
            }
        }

        //    console.log(TAG + '; OnMouseMove val2:' + val);
        if (Math.abs(val - this.value) > 10) return;
        //   console.log(TAG + '; OnMouseMove val:' + val);
        this.animate = requestAnimationFrame(this.draw.bind(this, val));
        if (this.value != Math.round(val)) {
            this.value = Math.round(val);
            this.change(this.value)
        }
        //   console.log(TAG + '; OnMouseMove end...');
    }

    OnMouseDown(evt) {
        //   console.log(TAG + ' ;OnMouseDown start...');
        let range = 10;
        let X = this.getx(evt);
        let Y = this.gety(evt);
        let P = this.P

        //        console.log(TAG + ' ;OnMouseDown X:' + X);
        //        console.log(TAG + ' ;OnMouseDown Y:' + Y);
        //        console.log(TAG + ' ;OnMouseDown P.x :' + P.x);
        //        console.log(TAG + ' ;OnMouseDown P.y :' + P.y);

        let minX = P.x - this.slider - range;
        let maxX = P.x + this.slider + range;
        let minY = P.y - this.slider - range;
        let maxY = P.y + this.slider + range;

        //        console.log(TAG + ' ;OnMouseDown minX :' + minX);
        //        console.log(TAG + ' ;OnMouseDown maxX :' + maxX);
        //        console.log(TAG + ' ;OnMouseDown minY:' + minY);
        //        console.log(TAG + ' ;OnMouseDown maxY :' + maxY);


        if (minX < X && X < maxX && minY < Y && Y < maxY) { //判断鼠标是否在滑块上
            this.isDown = true;
        } else {
            this.isDown = false;
        }
        console.log(TAG + 'OnMouseDown end...');
    }

    OnMouseUp() { //鼠标释放
        const _this = this
        cancelAnimationFrame(_this.animate);
        this.isDown = false
        console.log(TAG + 'OnMouseUp end...');
    }

    // 将坐标点转化为弧度
    XYToDeg(lx, ly) {
        console.log(TAG + '; XYToDeg ...lx:' + lx);
        console.log(TAG + '; XYToDeg ...ly:' + ly);
        let adeg = Math.atan(ly / lx)
        let deg;
        if (lx >= 0 && ly >= 0) {
            deg = adeg;
        }
        if (lx <= 0 && ly >= 0) {
            deg = adeg + Math.PI;
        }
        if (lx <= 0 && ly <= 0) {
            deg = adeg + Math.PI;
        }
        if (lx > 0 && ly < 0) {
            deg = adeg + Math.PI * 2;
        }
        return deg
    }

    //获取鼠标在canvas内坐标x
    getx(ev) {
        return ev.touches[0].localX;
    }

    //获取鼠标在canvas内坐标y
    gety(ev) {
        return ev.touches[0].localY;
    }

    //节流
    throttle(func) {
        let previous = 0;
        return function () {
            let now = Date.now();
            let context = this;
            let args = arguments;
            if (now - previous > 10) {
                func.apply(context, args);
                previous = now;
            }
        }
    }
}

//function main(){
//    const dom = document.getElementById("content")
//    const a = new DragAcr({
//        el: dom,
//        startDeg: 0.5,
//        endDeg: 2.5,
//        outColor: '#eee',
//        counterclockwise: true,
//        change: (v)=> {
//            console.log(`value:${v}`)
//        }
//    })
//}
